package ace.module.oss.core.impl.manager.impl.ossmgr;

import ace.module.oss.core.impl.dao.entity.OssApplicationConfig;
import ace.module.oss.core.impl.dao.entity.OssSupplier;
import ace.module.oss.core.impl.manager.OssManager;
import cn.hutool.core.io.file.FileNameUtil;
import cn.hutool.core.util.IdUtil;
import java.util.HashMap;
import java.util.Map;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.text.StringSubstitutor;
import org.dromara.x.file.storage.core.FileInfo;
import org.dromara.x.file.storage.core.FileStorageService;
import org.dromara.x.file.storage.core.upload.UploadPretreatment;

/**
 * @author caspar
 * @date 2024/5/21 11:46
 */
@Slf4j
public class DefaultOssManager implements OssManager {
  @Getter(AccessLevel.PROTECTED)
  private final OssApplicationConfig ossApplicationConfig;

  @Getter(AccessLevel.PROTECTED)
  private final OssSupplier ossSupplier;

  @Getter(AccessLevel.PROTECTED)
  private final FileStorageService fileStorageService;

  public DefaultOssManager(
      OssApplicationConfig ossApplicationConfig,
      OssSupplier ossSupplier,
      FileStorageService fileStorageService) {
    this.ossApplicationConfig = ossApplicationConfig;
    this.ossSupplier = ossSupplier;
    this.fileStorageService = fileStorageService;
  }

  @Override
  public String upload(Object uploadFile) {
    UploadPretreatment uploadPretreatment = this.getFileStorageService().of(uploadFile);
    this.uploadBefore(uploadPretreatment);
    FileInfo fileInfo = uploadPretreatment.upload();
    String url = this.getUrlByFileInfo(fileInfo);
    return url;
  }

  protected void uploadBefore(UploadPretreatment uploadPretreatment) {
    String saveFileName = this.getFileName(uploadPretreatment);
    uploadPretreatment.setSaveFilename(saveFileName);
    uploadPretreatment.setPath(this.getSaveDir());
  }

  protected String getSaveDir() {
    if (StringUtils.isEmpty(this.ossApplicationConfig.getCatalog())) {
      return StringUtils.EMPTY;
    }
    return this.ossApplicationConfig.getCatalog() + "/";
  }

  protected String getFileName(UploadPretreatment uploadPretreatment) {
    String fileFullExt = this.getFileFulLExt(uploadPretreatment.getOriginalFilename());
    String fileOnlyName = this.getFileOnlyName(uploadPretreatment.getOriginalFilename());
    Map<String, String> data = new HashMap<>();
    data.put("fileOnlyName", fileOnlyName);
    data.put("fileFullExt", fileFullExt);
    data.put("fileId", IdUtil.objectId());
    String fileName = StringSubstitutor.replace("${fileOnlyName}_${fileId}${fileFullExt}", data);
    return fileName;
  }

  protected String getFileOnlyName(String fileName) {
    if (StringUtils.isNotEmpty(fileName)) {
      int lastIndex = fileName.lastIndexOf(".");
      if (lastIndex == -1) {
        return fileName;
      }
      return fileName.substring(0, lastIndex);
    }
    return fileName;
  }

  protected String getFileFulLExt(String fileName) {
    String fileFullExt = FileNameUtil.getSuffix(fileName);
    if (StringUtils.isNotEmpty(fileFullExt)) {
      fileFullExt = "." + fileFullExt;
    }
    return fileFullExt;
  }

  protected String getUrlByFileInfo(FileInfo fileInfo) {
    return fileInfo.getUrl();
  }
}
